<template>
  <div v-show="!showDetail">
    <div class="container">
      <div class="left-panel">
        <div class="top-title">选择变量</div>
        <div id="g1">
          <div v-for="item in paramsList" :key="item.dictId" class="list_item" :data-id="item.dictId"> {{
            item.dictName }} </div>
        </div>
      </div>
      <div class="flexible-panel">
        <div class="top-title">
          <div>{{ showType }}</div>
          <div class="close-icon" @click="emitter.emit('closeNewApprove')"></div>
        </div>
        <XBOOST v-if="showType == 'XGBoost回归'"></XBOOST>
        <TREESVR v-if="showType == '决策树回归'"></TREESVR>
        <KNN v-if="showType == 'K近邻（KNN）回归'"></KNN>
        <FOREST v-if="showType == '随机森林回归'"></FOREST>
        <div class="var-des">
          选择变量Y （变量数=1）
        </div>
        <div class="drag-area">
          <div class="drag-box">
            <div class="list-item">
              <div>融资金额</div>
            </div>
          </div>
        </div>
        <div class="var-des">
          选择自变量x （变量数≥5）
        </div>
        <div class="drag-areax" id="g2">
          <div class="drag-box" v-if="xList.length == 0">
            <div class="yStyle">拖入自变量x</div>
          </div>
          <div class="drag-box" v-else>
            <div v-for="item in xList" class="list-item" :data-id="item.dictId">
              <div>{{ item.dictName }}</div>
              <div class="close-icon" @click="deleteItem(item)"></div>
            </div>
          </div>
        </div>
        <div class="condition">
          <div class="paramsBottom">
            <span>数据洗牌：</span>
            <el-select v-model="params.ShuffleData">
              <el-option label="是" :value="true" />
              <el-option label="否" :value="false" />
            </el-select>
            <el-tooltip popper-class="box-item-draggle" effect="dark" content="将数据重新打乱顺序按照训练重新分割数据。"
              placement="top-start">
              <el-icon style="margin-left: 10px;">
                <QuestionFilled />
              </el-icon>
            </el-tooltip>
          </div>
          <div class="paramsBottom" style="margin-left:50px">
            <span style="width:100px">训练占比：</span>
            <el-input-number type="number" v-model="params.TrainingPercentage" :min="0.5" :max="0.8" :precision="1"
              :step="0.1"></el-input-number>
            <el-tooltip popper-class="box-item-draggle" effect="dark" content="样本量中参与模型训练的比例。" placement="top-start">
              <el-icon style="margin-left: 10px;">
                <QuestionFilled />
              </el-icon>
            </el-tooltip>
          </div>
          <div class="paramsBottom" style="margin-left:50px">
            <span>交叉验证：</span>
            <el-select v-model="params.CrossValidation">
              <el-option label="是" :value="true" />
              <el-option label="否" :value="false" />
            </el-select>
            <el-tooltip popper-class="box-item-draggle" effect="dark"
              content="k折交叉验证将数据集划分为k个大小相似的互斥子集，每次用k-1个子集
                                                                                                                                                                                                                                                                                                                                                                                                           的并集作为训练集，剩下的那一个子集作测试集，进行k次训练和测试，
                                                                                                                                                                                                                                                                                                                                                                                                            最后返回k个评估结果的均值。可以避免由于数据集划分不合理而导致的
                                                                                                                                                                                                                                                                                                                                                                                                           在训练集上过拟合问题。"
              placement="top-start">
              <el-icon style="margin-left: 10px;">
                <QuestionFilled />
              </el-icon>
            </el-tooltip>
          </div>
        </div>
        <div style="margin-left: 20px;" class="detail" @click="settingDialog = true">更多设置>
        </div>
        <div class="foot-buttom">
          <el-button @click="handleDateDefault('reset')"> 重置 </el-button>
          <el-button @click="saveParams" type="primary">开始分析</el-button>
        </div>
      </div>
    </div>
  </div>
  <div v-if="showDetail">
    <div style="width:100%;height:100%">
      <div class="result-header">
        {{ showType }}
      </div>
      <div class="analy-result-process-wrap">
        <div class="analy-result-process-header">分析流程</div>
      </div>
      <div class="analy-result-process-content">
        <div class="process-header">
          <el-icon class='database' :size="25">
            <Coin />
          </el-icon>
          <span style="line-height: 20px; font-weight: 700;">
            数据源
          </span>
        </div>
        <div class="process-body">
          <span class="body-1">电商企业供应商数据</span>
        </div>
      </div>
      <div class="analy-result-process-content">
        <div class="process-header">
          <el-icon class='database' :size="25">
            <HelpFilled />
          </el-icon>
          <span style="line-height: 20px; font-weight: 700;">
            算法配置
          </span>
        </div>
        <div class="process-body">
          <p class="body-p">算法：{{ showType }}</p>
          <p class="body-p">变量：变量X：｛{{ xListStr }}｝;变量Y：{融资金额} </p>
        </div>
      </div>
      <div class="analy-result-process-content">
        <div class="process-header">
          <el-icon class='database' :size="25">
            <Tickets />
          </el-icon>
          <span style="line-height: 20px; font-weight: 700;">
            分析结果
          </span>
        </div>
        <div class="process-body">
          <p class="body-p" v-if="showType !== '线性回归'">{{ showType }}基于MSE、RMSE、MAE、MAPE、R²指标对模型进行评价，请看详细结论。</p>
          <p class="body-p" v-else>线性回归用于研究自变量与因变量之间的线性关系：F检验的显著性P值为0.000***，水平上呈现显著性，拒绝回归系数为0的原假设，因此模型基本满足要求。</p>
        </div>
      </div>
      <!-- 分析步骤 -->
      <div class="analy-step">
        <div class="analy-result-process-wrap">
          <div class="analy-result-process-header">分析步骤</div>
        </div>
        <div v-if="showType == 'XGBoost回归'">
          <div class="step-text">
            1.通过训练集数据来建立XGBoost回归模型。
          </div>
          <div class="step-text">
            2.通过建立的XGBoost来计算特征重要性。
          </div>
          <div class="step-text">
            3.将建立的XGBoost回归模型应用到训练、测试数据，得到模型评估结果。
          </div>
          <div class="step-text">
            4.由于XGBoost具有随机性，每次运算的结果不一样，若保存本次训练模型，后续可以直接上传数据代入到本次训练模型进行计算预测。
          </div>
          <div class="step-text">
            5.注：XGBoost无法像传统模型一样得到确定的方程，通常通过测试数据预测精度来对模型进行评价。
          </div>
        </div>
        <div v-if="showType == '决策树回归'">
          <div class="step-text">
            1.通过训练集数据来建立决策数回归模型，得到决策树结构。
          </div>
          <div class="step-text">
            2.通过建立的决策树来计算特征重要性。
          </div>
          <div class="step-text">
            3.将建立的决策树回归模型应用到训练、测试数据，得到模型评估结果。
          </div>
          <div class="step-text">
            4.由于决策树具有随机性，每次运算的结果不一样，若保存本次训练模型，后续可以直接上传数据代入到本次训练模型进行计算预测。
          </div>
          <div class="step-text">
            5.注：决策树无法像传统模型一样得到确定的方程，通常通过测试数据预测精度来对模型进行评价。
          </div>
        </div>
        <div v-if="showType == 'K近邻（KNN）回归'">
          <div class="step-text">
            1.通过训练集数据来建立K近邻(KNN)回归模型。
          </div>
          <div class="step-text">
            2.将建立的K近邻(KNN)回归模型应用到训练、测试数据，得到模型评估结果。
          </div>
          <div class="step-text">
            3.若K近邻(KNN)选择了数据洗牌功能，每次运算的结果不一样，若保存本次训练模型，后续可以直接上传数据代入到本次训练模型进行计算预测。
          </div>
          <div class="step-text">
            4.
            注：K近邻(KNN)无法像传统模型一样得到确定的方程，通常通过测试数据预测精度来对模型进行评价。
          </div>
        </div>
        <div v-if="showType == '随机森林回归'">
          <div class="step-text">
            1.通过训练集数据来建立随机森林回归模型。</div>
          <div class="step-text">
            2.通过建立的随机森林来计算特征重要性。
          </div>
          <div class="step-text">
            3.将建立的随机森林回归模型应用到训练、测试数据，得到模型评估结果。 </div>
          <div class="step-text">
            4.由于随机森林具有随机性，每次运算的结果不一样，若保存本次训练模型，后续可以直接上传数据代入到本次训练模型进行计算预测。
          </div>
          <div class="step-text">
            5.注：随机森林无法像传统模型一样得到确定的方程，通常通过测试数据预测精度来对模型进行评价。
          </div>
        </div>
      </div>
      <div class="analy-step">
        <div class="analy-result-process-wrap">
          <div class="analy-result-process-header">详细结论</div>
        </div>
        <div>
          <div class="result-table">
            <span class="sub-title-text">
              输出结果1：模型评估结果
            </span>
            <table style="text-align: center;width:95%">
              <tr>
                <th></th>
                <th>MSE</th>
                <th>RMSE</th>
                <th>MAE</th>
                <th>MAPE</th>
                <th>R²</th>
              </tr>
              <tbody>
                <tr>
                  <td>训练集</td>
                  <td>{{ bpSvrDetailData.mse }}</td>
                  <td>{{ bpSvrDetailData.rmse }}</td>
                  <td>{{ bpSvrDetailData.mae }}</td>
                  <td>{{ bpSvrDetailData.mape }}</td>
                  <td>{{ bpSvrDetailData.r2 }}</td>
                </tr>
                <!-- <tr>
                  <td>测试集</td>
                  <td>{{ bpSvrDetailData.mse_test }}</td>
                  <td>{{ bpSvrDetailData.rmse_test }}</td>
                  <td>{{ bpSvrDetailData.mae_test }}</td>
                  <td>{{ bpSvrDetailData.mape_test }}</td>
                  <td>{{ bpSvrDetailData.r2_test }}</td>
                </tr> -->
              </tbody>
            </table>
          </div>
          <div class="step-text">
            上表中展示了交叉验证集、训练集和测试集的预测评价指标，通过量化指标来衡量bp神经网络回归的预测效果。其中，通过交叉验证集的评价指标可以不断调整超参数，以得到可靠稳定的模型。
          </div>
          <div class="step-text">
            ● MSE（均方误差）： 预测值与实际值之差平方的期望值。取值越小，模型准确度越高。
          </div>
          <div class="step-text">
            ● RMSE（均方根误差）：为MSE的平方根，取值越小，模型准确度越高。
          </div>
          <div class="step-text">
            ● MAE（平均绝对误差）： 绝对误差的平均值，能反映预测值误差的实际情况。取值越小，模型准确度越高。
          </div>
          <div class="step-text">
            ● MAPE（平均绝对百分比误差）： 是 MAE 的变形，它是一个百分比值。取值越小，模型准确度越高。
          </div>
          <div class="step-text">
            ● R²： 将预测值跟只使用均值的情况下相比，结果越靠近 1 模型准确度越高。
          </div>
          <div class="result-table">
            <span class="sub-title-text">
              输出结果2：预测结果
              <el-select v-model="tableChange" @change="hanldeChangeTable" style="margin-left: 58%;">
                <el-option label="测试集" :value="1" />
                <el-option label="训练集" :value="2" />
              </el-select>
            </span>
            <table style="text-align: center; margin-bottom: 20px; width:95%" id="myTable" v-show="tableChange == 1">
              <thead>
                <tr>
                  <th>预测测试集结果Y</th>
                  <th v-for="item in bpSvrDetailData.bpSvrDetailHeader">{{ item }}</th>
                </tr>
              </thead>
            </table>
            <table style="text-align: center; margin-bottom: 20px; width:95%;" id="myTable1" v-if="tableChange == 2">
              <thead>
                <tr>
                  <th>预测结果集结果Y</th>
                  <th v-for="item in bpSvrDetailData.bpSvrDetailHeader">{{ item }}</th>
                </tr>
              </thead>
            </table>
          </div>
        </div>
      </div>
      <div class="foot-buttom">
        <div v-if="!!detailData">
          <el-button @click="emitter.emit('closeNewApprove')"> 关闭 </el-button>
        </div>
        <div v-else>
          <el-button @click="backToNew"> 返回 </el-button>
          <el-button @click="confirmVisible = true" type="primary">保存</el-button>
        </div>
      </div>
    </div>
  </div>
  <!-- 确认提交弹窗 -->
  <ReDialog :width="600" :height="200" :models="confirmVisible" @Closes="confirmVisible = false">
    <template #header>
      <h2 style=" text-align: center;">确认保存模型</h2>
    </template>
    <template #main>
      <div style="display:flex;justify-content: center;">
        <h3>请输入模型名称:</h3> <el-input v-model="params.modelName" style="width:200px;margin-left:20px"></el-input>
      </div>
    </template>
    <template #footer>
      <span class="dialog-footer">
        <el-button @click="saveSSS()" type="primary">确定</el-button>
        <el-button @click="confirmVisible = false"> 取消 </el-button>
      </span>
    </template>
  </ReDialog>
  <!-- 算法参数设置 -->
  <el-dialog v-model="settingDialog" :close-on-click-modal="false" width="50%">
    <template #header>
      <h2 style="text-align: center;">模型参数设置</h2>
    </template>
    <el-scrollbar height="500px">
      <!-- XGBoost回归 -->
      <div v-if="showType == 'XGBoost回归'" style="  margin-top: 15px;margin-left: 20px;">
        <div class="setting-item">
          <span>基学习器</span>
          <el-select style="margin-left: 85px;" v-model="XGBoostConfig.BaseLearner">
            <el-option label="gbtree(梯度提升树）" :value="'gbtree'" />
            <el-option label="gblinear（线性分类器）" :value="'gblinear'" />
            <el-option label="dart（带dropout的梯度提升树）" :value="'dart'" />
          </el-select>
          <el-tooltip popper-class="box-item-draggle" effect="dark" placement="top-start">
            <template #content>● 参数表示选择哪种 boost学习器，它总共有两大种选择（决策树与线性模型），三个具体选择。<br />● gbtree 和 dart 使用基于树的模型，而 gblinear
              使用线性模型。</template>
            <el-icon style="margin-left: 10px;">
              <QuestionFilled />
            </el-icon>
          </el-tooltip>
        </div>
        <div class="setting-item">
          <span>基学习器数量</span>
          <el-input-number type="number" v-model="XGBoostConfig.NumBaseLearners" :min="2" :max="1000"
            style="margin-left: 57px;"></el-input-number>
          <el-tooltip popper-class="box-item-draggle" effect="dark" placement="top-start">
            <template #content>XGBoost是不断在当前基学习器的基础上构建下一个基学习器。参数代表构建的
              弱学习器数量，数量增加时会提升拟合能力，但是会增加运算时间和过拟合概率
            </template>
            <el-icon style="margin-left: 10px;">
              <QuestionFilled />
            </el-icon>
          </el-tooltip>
        </div>
        <div class="setting-item">
          <span>学习率</span>
          <el-input-number type="number" v-model="XGBoostConfig.LearningRate" :min="0.0001" :precision="4" :max="1.0000"
            style="margin-left: 100px;" :step="0.0001"></el-input-number>
          <el-tooltip popper-class="box-item-draggle" effect="dark" placement="top-start">
            <template #content>合适的学习率能够使目标函数在合适的时间内收敛到局部最小值。<br />● 学习率设置太小，结果收敛非常缓慢。
              <br />● 学习率设置太大，结果在最优值附近徘徊，难以收敛。
            </template>
            <el-icon style="margin-left: 10px;">
              <QuestionFilled />
            </el-icon>
          </el-tooltip>
        </div>
        <div style='width: 900px;height: 1px;background: rgb(238, 241, 245);margin: 20px 0px;'></div>
        <div style="color:rgb(170, 173, 177);font-size: 14px;margin-bottom: 10px; margin-top:20px" class="setting-item">
          样本（行）和特征（列）采样情况
          <el-tooltip popper-class="box-item-draggle" effect="dark" placement="top-start">
            <template #content>可以控制模型过拟合
            </template>
            <el-icon style="margin-left: 10px;">
              <QuestionFilled />
            </el-icon>
          </el-tooltip>
        </div>
        <div class="setting-item">
          <span>样本采样率</span>
          <el-input-number type="number" v-model="XGBoostConfig.SampleRate" :min="0.1" :max="1.0" :precision="1"
            style="margin-left: 70px;" :step="0.1"></el-input-number>
          <el-tooltip popper-class="box-item-draggle" effect="dark" placement="top-start">
            <template #content>每颗树的生成可以不去全部样本，控制模型的过拟合。
            </template>
            <el-icon style="margin-left: 10px;">
              <QuestionFilled />
            </el-icon>
          </el-tooltip>
        </div>
        <div class="setting-item">
          <span>树特征采样率</span>
          <el-input-number type="number" v-model="XGBoostConfig.TreeFeatureSamplingRate" :min="0.1" :max="1.0"
            :precision="1" style="margin-left: 57px;" :step="0.1"></el-input-number>
          <el-tooltip popper-class="box-item-draggle" effect="dark" placement="top-start">
            <template #content>即每棵树不使用全部的特征，控制模型的过拟合。
            </template>
            <el-icon style="margin-left: 10px;">
              <QuestionFilled />
            </el-icon>
          </el-tooltip>
        </div>
        <div class="setting-item">
          <span>节点特征采样率</span>
          <el-input-number type="number" v-model="XGBoostConfig.NodeFeatureSamplingRate" :min="0.1" :max="1.0"
            :precision="1" style="margin-left: 45px;" :step="0.1"></el-input-number>
          <el-tooltip popper-class="box-item-draggle" effect="dark" placement="top-start">
            <template #content>即每次分裂都不取全部变量，控制模型的过拟合。
            </template>
            <el-icon style="margin-left: 10px;">
              <QuestionFilled />
            </el-icon>
          </el-tooltip>
        </div>
        <div style='width: 900px;height: 1px;background: rgb(238, 241, 245);margin: 20px 0px;'></div>
        <div style="color:rgb(170, 173, 177);font-size: 14px;margin-bottom: 10px; margin-top:20px" class="setting-item">
          节点分裂设置
          <el-tooltip popper-class="box-item-draggle" effect="dark" placement="top-start">
            <template #content>即每次分裂都不取全部变量，控制模型的过拟合。
            </template>
            <el-icon style="margin-left: 10px;">
              <QuestionFilled />
            </el-icon>
          </el-tooltip>
        </div>
        <div class="setting-item">
          <span>叶子节点中样本的最小权重</span>
          <el-input-number type="number" v-model="XGBoostConfig.MinLeafWeight" :min="0.000" :max="0.005" :precision="3"
            style="margin-left: 70px;" :step="0.001"></el-input-number>
          <el-tooltip popper-class="box-item-draggle" effect="dark" placement="top-start">
            <template #content>● 若叶子节点样本权重小于该值，则会和兄弟节点一起被剪枝。
              <br />● 默认是0，就是不考虑权重问题。
              <br />● 一般来说，如果数据集有较多样本有缺失值，或者分类树样本的分布类别偏差很大，就需要会引入样本权重。
            </template>
            <el-icon style="margin-left: 10px;">
              <QuestionFilled />
            </el-icon>
          </el-tooltip>
        </div>
        <div style='width: 900px;height: 1px;background: rgb(238, 241, 245);margin: 20px 0px;'></div>
        <div style="color:rgb(170, 173, 177);font-size: 14px;margin-bottom: 10px; margin-top:20px" class="setting-item">
          树的规模设置
          <el-tooltip popper-class="box-item-draggle" effect="dark" placement="top-start">
            <template #content>可以控制树的规模
            </template>
            <el-icon style="margin-left: 10px;">
              <QuestionFilled />
            </el-icon>
          </el-tooltip>
        </div>
        <div class="setting-item">
          <span>树的最大深度</span>
          <el-input-number type="number" v-model="XGBoostConfig.MaxTreeDepth" :min="1" style="margin-left: 60px;"
            :step="1"></el-input-number>
          <el-tooltip popper-class="box-item-draggle" effect="dark" placement="top-start">
            <template #content>● 树的深度达到该值后就停止分裂，避免无限往下划分。
              <br />● 若模型在样本量多，特征也多的情况下，可适当增加树的深度。
            </template>
            <el-icon style="margin-left: 10px;">
              <QuestionFilled />
            </el-icon>
          </el-tooltip>
        </div>
        <div style='width: 900px;height: 1px;background: rgb(238, 241, 245);margin: 20px 0px;'></div>
        <div style="color:rgb(170, 173, 177);font-size: 14px;margin-bottom: 10px; margin-top:20px" class="setting-item">
          正则化
        </div>
        <div class="setting-item">
          <span>L1正则化项</span>
          <el-input-number type="number" v-model="XGBoostConfig.L1Regularization" :min="0" style="margin-left: 70px;"
            :precision="1" :step="0.5"></el-input-number>
          <el-tooltip popper-class="box-item-draggle" effect="dark" placement="top-start">
            <template #content>● L1范数容易得到稀疏解,可以用于特征选择。一定程度上，L1也可以防止过拟合。
              <br />● 增加此值将增大惩罚，使模型更加保守。
            </template>
            <el-icon style="margin-left: 10px;">
              <QuestionFilled />
            </el-icon>
          </el-tooltip>
        </div>
        <div class="setting-item">
          <span>L2正则化项</span>
          <el-input-number type="number" v-model="XGBoostConfig.L2Regularization" :min="0" style="margin-left: 70px;"
            :precision="1" :step="0.5"></el-input-number>
          <el-tooltip popper-class="box-item-draggle" effect="dark" placement="top-start">
            <template #content>● L2范数容易得到平滑解,可以用来考虑降低过拟合。
              <br />● 增加此值将增大惩罚，使模型更加保守。
            </template>
            <el-icon style="margin-left: 10px;">
              <QuestionFilled />
            </el-icon>
          </el-tooltip>
        </div>
      </div>
      <!-- 决策树回归 -->
      <div v-if="showType == '决策树回归'" style=" margin-top: 15px;margin-left: 20px;">
        <div class="setting-item">
          <span>节点分裂评价准则</span>
          <el-select style="margin-left: 100px;" v-model="decisionTreeRegressionConfig.splittingCriterion">
            <el-option label="friedman_mse(改进分数的均方误差）" :value="'friedman_mse'" />
            <el-option label="mse（均方误差）" :value="'squared_error'" />
            <el-option label="mae(平均绝对误差）" :value="'absolute_error'" />
            <el-option label="poisson(泊松误差)" :value="'poisson'" />
          </el-select>
          <el-tooltip popper-class="box-item-draggle" effect="dark" placement="top-start">
            <template #content>● L2范数容易得到平滑解,可以用来考虑降低过拟合。
              <br />● 增加此值将增大惩罚，使模型更加保守。
            </template>
            <el-icon style="margin-left: 10px;">
              <QuestionFilled />
            </el-icon>
          </el-tooltip>
        </div>
        <div class="setting-item">
          <span>特征划分点选择标准</span>
          <el-select style="margin-left: 85px;" v-model="decisionTreeRegressionConfig.splittingFeatureCriterion">
            <el-option label="best" :value="'best'" />
            <el-option label="random" :value="'random'" />
          </el-select>
          <el-tooltip popper-class="box-item-draggle" effect="dark" placement="top-start">
            <template #content>● best在特征的所有划分点中找出最优的划分点。<br />● random是随机的在部分划分点中找局部最优的划分点。<br />● 若样本数据量非常大，推荐"random"。
            </template>
            <el-icon style="margin-left: 10px;">
              <QuestionFilled />
            </el-icon>
          </el-tooltip>
        </div>
        <div class="setting-item">
          <span>划分时最大特征比例</span>
          <el-select style="margin-left: 85px;" v-model="decisionTreeRegressionConfig.MaxFeatureRatio">
            <el-option label="无" :value="'无'" />
            <el-option label="auto(sqrt)" :value="'auto'" />
            <el-option label="自定义" :value="'custom'" />
          </el-select>
          <el-tooltip popper-class="box-item-draggle" effect="dark"
            content="当特征数较多时，为控制树的生成时间，每次切分只考虑部分比例特征来进行分裂。
                                                                                                                                                                                                                                                                                                                                                auto：使用样本总特征数的开方数来进行建模。"
            placement="top-start">
            <el-icon style="margin-left: 10px;">
              <QuestionFilled />
            </el-icon>
          </el-tooltip>
          <el-input-number type="number" v-model="decisionTreeRegressionConfig.FeatureRatioValue" :min="0.1" :max="0.9"
            :precision="1" style="margin-left:71px;" :step="0.1"
            v-if="decisionTreeRegressionConfig.MaxFeatureRatio == 'custom'"></el-input-number>
        </div>
        <div style='width: 900px;height: 1px;background: rgb(238, 241, 245);margin: 20px 0px;'></div>
        <div style="color:rgb(170, 173, 177);font-size: 14px;margin-bottom: 10px; margin-top:20px" class="setting-item">
          节点分裂设置
          <el-tooltip popper-class="box-item-draggle" effect="dark" placement="top-start">
            <template #content>可以限制子树继续划分
            </template>
            <el-icon style="margin-left: 10px;">
              <QuestionFilled />
            </el-icon>
          </el-tooltip>
        </div>
        <div class="setting-item">
          <span>内部节点分裂的最小样本数</span>
          <el-input-number type="number" v-model="decisionTreeRegressionConfig.minInternalNodeSamples" :min="2"
            style="margin-left: 70px;" :step="1"></el-input-number>
          <el-tooltip popper-class="box-item-draggle" effect="dark" placement="top-start">
            <template #content>● 某内部节点的样本量小于该值，就不再进行分裂。
              <br />● 若样本量较多，可适当增加该值以避免某个特征类别只适用于极小量的样本，它从根节点就开始避免过拟合。
            </template>
            <el-icon style="margin-left: 10px;">
              <QuestionFilled />
            </el-icon>
          </el-tooltip>
        </div>
        <div class="setting-item">
          <span>叶子节点的最小样本数</span>
          <el-input-number type="number" v-model="decisionTreeRegressionConfig.minLeafNodeSamples" :min="1"
            style="margin-left: 98px;" :step="1"></el-input-number>
          <el-tooltip popper-class="box-item-draggle" effect="dark" placement="top-start">
            <template #content>● 若叶子节点样本数小于该值，则会和兄弟节点一起被剪枝。
              <br />● 若样本量较多，可适当增加该值以避免某个特征类别只适用于极小量的样本导致的过拟合。
            </template>
            <el-icon style="margin-left: 10px;">
              <QuestionFilled />
            </el-icon>
          </el-tooltip>
        </div>
        <div class="setting-item">
          <span>叶子节点中样本的最小权重</span>
          <el-input-number type="number" v-model="decisionTreeRegressionConfig.minLeafNodeWeight" :min="0.000"
            :max="0.500" style="margin-left: 70px;" :step="0.001" :precision="3"></el-input-number>
          <el-tooltip popper-class="box-item-draggle" effect="dark" placement="top-start">
            <template #content>● 若叶子节点样本权重小于该值，则会和兄弟节点一起被剪枝。
              <br />● 默认是0，就是不考虑权重问题。
              <br />● 一般来说，如果数据集有较多样本有缺失值，或者分类树样本的分布类别偏差很大，就需要会引入样本权重。
            </template>
            <el-icon style="margin-left: 10px;">
              <QuestionFilled />
            </el-icon>
          </el-tooltip>
        </div>
        <div style='width: 900px;height: 1px;background: rgb(238, 241, 245);margin: 20px 0px;'></div>
        <div style="color:rgb(170, 173, 177);font-size: 14px;margin-bottom: 10px; margin-top:20px" class="setting-item">
          树的规模设置
          <el-tooltip popper-class="box-item-draggle" effect="dark" placement="top-start">
            <template #content>可以控制树的规模
            </template>
            <el-icon style="margin-left: 10px;">
              <QuestionFilled />
            </el-icon>
          </el-tooltip>
        </div>
        <div class="setting-item">
          <span>树的最大深度</span>
          <el-input-number type="number" v-model="decisionTreeRegressionConfig.maxTreeDepth" :min="1"
            style="margin-left: 110px;" :step="1"></el-input-number>
          <el-tooltip popper-class="box-item-draggle" effect="dark" placement="top-start">
            <template #content>● 树的深度达到该值后就停止分裂，避免无限往下划分。
              <br />● 若模型在样本量多，特征也多的情况下，可适当增加树的深度。
            </template>
            <el-icon style="margin-left: 10px;">
              <QuestionFilled />
            </el-icon>
          </el-tooltip>
        </div>
        <div class="setting-item">
          <span>叶子节点的最大数量</span>
          <el-input-number type="number" v-model="decisionTreeRegressionConfig.maxLeafNodeCount" :min="2"
            style="margin-left: 70px;" :step="1"></el-input-number>
          <el-tooltip popper-class="box-item-draggle" effect="dark" placement="top-start">
            <template #content><br />● 叶子节点数达到该值后就停止分裂，避免出现无限多的划分类别。
              <br />● 若模型在样本量多，特征也多的情况下，可适当增加叶子节点的最大数量。
            </template>
            <el-icon style="margin-left: 10px;">
              <QuestionFilled />
            </el-icon>
          </el-tooltip>
        </div>
        <div class="setting-item">
          <span>节点划分不纯度的阀值</span>
          <el-input-number type="number" v-model="decisionTreeRegressionConfig.impurityThreshold" :min="0.000"
            :max="1.000" style="margin-left: 55px;" :step="0.001" :precision="3"></el-input-number>
          <el-tooltip popper-class="box-item-draggle" effect="dark" placement="top-start">
            <template #content><br />● 若某节点的不纯度(gini、entropy等)小于这个阈值，则该节点不再生成子节点。
              <br />● 若模型在样本量多，特征也多的情况下，可适当增大该值。
            </template>
            <el-icon style="margin-left: 10px;">
              <QuestionFilled />
            </el-icon>
          </el-tooltip>
        </div>
      </div>
      <!-- K近邻（KNN）回归 -->
      <div v-if="showType == 'K近邻（KNN）回归'" style=" margin-top: 15px;margin-left: 20px;">
        <div class="setting-item">
          <span>搜索算法</span>
          <el-select style="margin-left: 100px;" v-model="knnConfig.searchMethod">
            <el-option label="AUTO" :value="'auto'" />
            <el-option label="线性扫描" :value="'brute'" />
            <el-option label="KD树" :value="'kd_tree'" />
            <el-option label="球树" :value="'ball_tree'" />
          </el-select>
          <el-tooltip popper-class="box-item-draggle" effect="dark" placement="top-start">
            <template #content>用于寻找最近K个值的算法：<br />● K近邻法的最简单实现是线性扫描，需要计算待测样本与每一个训练样本的距离，当训练集很大时，计算非常耗时。
              <br />● 为了提高K近邻搜索的效率，可以考虑使用kd树或者球树来以减少计算距离的次数。
              <br />● auto将自动确定适合的方法。
            </template>
            <el-icon style="margin-left: 10px;">
              <QuestionFilled />
            </el-icon>
          </el-tooltip>
        </div>
        <div class="setting-item" v-if="knnConfig.searchMethod == 'kd_tree' || knnConfig.searchMethod == 'ball_tree'">
          <span>叶的数量</span>
          <el-input-number type="number" v-model="knnConfig.numberLeaves" :min="2" :max="100" style="margin-left: 100px;"
            :step="1"></el-input-number>
          <el-tooltip popper-class="box-item-draggle" effect="dark" placement="top-start">
            <template #content>● 如果搜索算法为KD树或者球树时，这个参数决定树的规模。
              <br />● 若样本量较大、特征量较大情况下，可适当增加该值。
            </template>
            <el-icon style="margin-left: 10px;">
              <QuestionFilled />
            </el-icon>
          </el-tooltip>
        </div>
        <div class="setting-item">
          <span>近邻数</span>
          <el-select style="margin-left: 112px;" v-model="knnConfig.nearestNeighbors">
            <el-option :key="item" :label="item" :value="item" v-for="item in 31" :disabled="item == 1" />
          </el-select>
          <el-tooltip popper-class="box-item-draggle" effect="dark" placement="top-start">
            <template #content>
              ● KNN回归器一般将离它最近的k个观察值中的标签值进行平均处理。
              <br />● 近邻数要根据样本量适当选取，值过大会导致模型简化而失去意义，值过小则会将模型复杂化并产生过拟合现象。</template>
            <el-icon style="margin-left: 10px;">
              <QuestionFilled />
            </el-icon>
          </el-tooltip>
        </div>
        <div class="setting-item">
          <span>近邻样本权重函数</span>
          <el-select style="margin-left: 43px;" v-model="knnConfig.weightingFunction">
            <el-option label="所有最近邻权重一致" :value="'uniform'" />
            <el-option label="权重和距离成反比例" :value="'distance'" />
          </el-select>
          <el-tooltip popper-class="box-item-draggle" effect="dark" placement="top-start">
            <template #content>
              ● 此值用于标识k个近邻样本的权重。
              <br />● 一般来说，如果样本的分布是比较成簇的，即各类样本都在相对分开的簇中时，
              我们用默认的"所有最近邻权重一致"就可以了，如果样本的分布比较乱，规律不
              好寻找，选择"权重和距离成反比"是一个比较好的选择。
            </template>
            <el-icon style="margin-left: 10px;">
              <QuestionFilled />
            </el-icon>
          </el-tooltip>
        </div>
        <div class="setting-item">
          <span>向量距离算法</span>
          <el-select style="margin-left: 72px;" v-model="knnConfig.distanceAlgorithm">
            <el-option label="欧氏距离" :value="'2'" />
            <el-option label="曼哈顿距离" :value="'1'" />
            <el-option label="切比雪夫距离" :value="'3'" />
          </el-select>
          <el-tooltip popper-class="box-item-draggle" effect="dark" placement="top-start">
            <template #content>
              ● 特征空间中的两个实例点的距离是两个实例点相似程度的反映。
              <br />● 可自行选择任一距离度量公式，一般来说，“欧式距离”可以满足需求。
            </template>
            <el-icon style="margin-left: 10px;">
              <QuestionFilled />
            </el-icon>
          </el-tooltip>
        </div>
      </div>
      <!-- 随机森林回归 -->
      <div v-if="showType == '随机森林回归'" style=" margin-top: 15px;margin-left: 20px;">
        <div class="setting-item">
          <span>节点分裂评价准则</span>
          <el-select style="margin-left: 100px;" v-model="randomForestRegressionConfig.splittingCriterion">
            <el-option label="mse（均方误差）" :value="'squared_error'" />
            <el-option label="mae(平均绝对误差）" :value="'absolute_error'" />
          </el-select>
          <el-tooltip popper-class="box-item-draggle" effect="dark" placement="top-start">
            <template #content>● 在决策树构建的过程中我们总是选择使得信息不确定性减少得最多的特征来划分当前数据集。
              <br />● 用户可自行选择使用哪一个节点分裂评价准则。
            </template>
            <el-icon style="margin-left: 10px;">
              <QuestionFilled />
            </el-icon>
          </el-tooltip>
        </div>
        <div class="setting-item">
          <span>决策树数量</span>
          <el-input-number type="number" v-model="randomForestRegressionConfig.numDecisionTrees" :min="2" :max="100000"
            style="margin-left: 142px;" :step="1"></el-input-number>
          <el-tooltip popper-class="box-item-draggle" effect="dark" content="惩罚系数值越高，说明越不能容忍出现误差。" placement="top-start">
            <el-icon style="margin-left: 10px;">
              <QuestionFilled />
            </el-icon>
          </el-tooltip>
        </div>
        <div class="setting-item">
          <span>有放回采样</span>
          <el-select style="margin-left: 142px;" v-model="randomForestRegressionConfig.bootstrapSampling">
            <el-option label="是" :value="'true'" />
            <el-option label="否" :value="'false'" />
          </el-select>
          <el-tooltip popper-class="box-item-draggle" effect="dark"
            content="输入2-1000内的整数，包括2和1000。
                                                                                                                                                                                                                                                                                                                                                                                    问号图标悬浮显示注释：
                                                                                                                                                                                                                                                                                                                                                                                    随机森林回归是多棵决策树组合在一起的简单平均结果。
                                                                                                                                                                                                                                                                                                                                                                                    参数代表构建的决策树数量，数量增加时会提升拟合能力，
                                                                                                                                                                                                                                                                                                                                                                                    但是会增加运算时间和过拟合概率。
                                                                                                                                                                                                                                                                                                                                                                                    问号图标悬浮显示注释：当样本数量较多时，建议对每棵决策树进行有放回采样。"
            placement="top-start">
            <el-icon style="margin-left: 10px;">
              <QuestionFilled />
            </el-icon>
          </el-tooltip>
        </div>
        <div class="setting-item">
          <span>袋外测试数据</span>
          <el-select style="margin-left: 128px;" v-model="randomForestRegressionConfig.outOfBagTesting">
            <el-option label="是" :value="'true'" />
            <el-option label="否" :value="'false'" />
          </el-select>
          <el-tooltip popper-class="box-item-draggle" effect="dark" content="可用袋外数据测试结果来检验模型的泛化能力。" placement="top-start">
            <el-icon style="margin-left: 10px;">
              <QuestionFilled />
            </el-icon>
          </el-tooltip>
        </div>
        <div class="setting-item">
          <span>划分时最大特征比例</span>
          <el-select style="margin-left: 85px;" v-model="randomForestRegressionConfig.maxFeatureRatio">
            <el-option label="无" :value="'无'" />
            <el-option label="auto(sqrt)" :value="'auto'" />
            <el-option label="自定义" :value="'custom'" />
          </el-select>
          <el-tooltip popper-class="box-item-draggle" effect="dark"
            content="当特征数较多时，为控制树的生成时间，每次切分只考虑部分比例特征来进行分裂。
                                                                                                                                                                                                                                                                                                                                                  auto：使用样本总特征数的开方数来进行建模。"
            placement="top-start">
            <el-icon style="margin-left: 10px;">
              <QuestionFilled />
            </el-icon>
          </el-tooltip>
          <el-input-number type="number" v-model="randomForestRegressionConfig.featureRatioValue" :min="0.1" :max="0.9"
            :precision="1" style="margin-left:71px;" :step="0.1"
            v-if="randomForestRegressionConfig.maxFeatureRatio == 'custom'"></el-input-number>
        </div>
        <div style='width: 900px;height: 1px;background: rgb(238, 241, 245);margin: 20px 0px;'></div>
        <div style="color:rgb(170, 173, 177);font-size: 14px;margin-bottom: 10px; margin-top:20px" class="setting-item">
          节点分裂设置
          <el-tooltip popper-class="box-item-draggle" effect="dark" placement="top-start">
            <template #content>可以限制子树继续划分
            </template>
            <el-icon style="margin-left: 10px;">
              <QuestionFilled />
            </el-icon>
          </el-tooltip>
        </div>
        <div class="setting-item">
          <span>内部节点分裂的最小样本数
          </span>
          <el-input-number type="number" v-model="randomForestRegressionConfig.minInternalNodeSamples" :min="2"
            style="margin-left: 47px;" :step="1"></el-input-number>
          <el-tooltip popper-class="box-item-draggle" effect="dark" placement="top-start">
            <template #content>● 某内部节点的样本量小于该值，就不再进行分裂。。
              <br />● 若样本量较多，可适当增加该值以避免某个特征类别只适用于极小量的样本，它从根节点就开始避免过拟合。
            </template>
            <el-icon style="margin-left: 10px;">
              <QuestionFilled />
            </el-icon>
          </el-tooltip>
        </div>
        <div class="setting-item">
          <span>叶子节点的最小样本数</span>
          <el-input-number type="number" v-model="randomForestRegressionConfig.minLeafNodeSamples" :min="1"
            style="margin-left: 74px;" :step="1"></el-input-number>
          <el-tooltip popper-class="box-item-draggle" effect="dark" placement="top-start">
            <template #content>● 若叶子节点样本数小于该值，则会和兄弟节点一起被剪枝。
              <br />● 若样本量较多，可适当增加该值以避免某个特征类别只适用于极小量的样本导致的过拟合。
            </template>
            <el-icon style="margin-left: 10px;">
              <QuestionFilled />
            </el-icon>
          </el-tooltip>
        </div>
        <div class="setting-item">
          <span>叶子节点中样本的最小权重
          </span>
          <el-input-number type="number" v-model="randomForestRegressionConfig.minLeafNodeWeight" :min="0.000"
            :max="0.500" :precision="3" style="margin-left: 47px;" :step="0.001"></el-input-number>
          <el-tooltip popper-class="box-item-draggle" effect="dark" placement="top-start">
            <template #content>若叶子节点样本权重小于该值，则会和兄弟节点一起被剪枝。<br />● 默认是0，就是不考虑权重问题。
              <br />● 一般来说，如果数据集有较多样本有缺失值，或者分类树样本的分布类别偏差很大，就需要会引入样本权重。。
            </template>
            <el-icon style="margin-left: 10px;">
              <QuestionFilled />
            </el-icon>
          </el-tooltip>
        </div>
        <div style='width: 900px;height: 1px;background: rgb(238, 241, 245);margin: 20px 0px;'></div>
        <div style="color:rgb(170, 173, 177);font-size: 14px;margin-bottom: 10px; margin-top:20px" class="setting-item">
          树的规模设置
          <el-tooltip popper-class="box-item-draggle" effect="dark" placement="top-start">
            <template #content>隐藏层的意义就是把输入数据的特征，抽象到另一个维度空间，来展现其更抽象化的特征。<br />● 一般来说，一或两层的隐藏层已经能够解决很多问题了，如果数据量多，可以在防止出
              现过拟合的情况下适当的增加层数。
              <br />● 而隐藏层数量也要适当，一般来说，隐藏层的节点数必须小于n-1，其中n是训练样本数量
            </template>
            <el-icon style="margin-left: 10px;">
              <QuestionFilled />
            </el-icon>
          </el-tooltip>
        </div>
        <div class="setting-item">
          <span>树的最大深度
          </span>
          <el-input-number type="number" v-model="randomForestRegressionConfig.maxTreeDepth" :min="1"
            style="margin-left: 130px;" :step="1"></el-input-number>
          <el-tooltip popper-class="box-item-draggle" effect="dark" placement="top-start">
            <template #content>可以控制树的规模 </template>
            <el-icon style="margin-left: 10px;">
              <QuestionFilled />
            </el-icon>
          </el-tooltip>
        </div>
        <div class="setting-item">
          <span>叶子节点的最大数量
          </span>
          <el-input-number type="number" v-model="randomForestRegressionConfig.maxLeafNodeCount" :min="2"
            style="margin-left: 88px;" :step="1"></el-input-number>
          <el-tooltip popper-class="box-item-draggle" effect="dark" placement="top-start">
            <template #content>叶子节点数达到该值后就停止分裂，避免出现无限多的划分类别。<br />● 若模型在样本量多，特征也多的情况下，可适当增加叶子节点的最大数量。
              <br />● 学习率设置太大，结果在最优值附近徘徊，难以收敛。 </template>
            <el-icon style="margin-left: 10px;">
              <QuestionFilled />
            </el-icon>
          </el-tooltip>
        </div>
        <div class="setting-item">
          <span>节点划分不纯度的阀值
          </span>
          <el-input-number type="number" v-model="randomForestRegressionConfig.impurityThreshold" :min="0.000"
            :max="1.000" :precision="3" style="margin-left: 73px;" :step="0.001"></el-input-number>
          <el-tooltip popper-class="box-item-draggle" effect="dark" placement="top-start">
            <template #content>若某节点的不纯度(均方差，绝对差等)小于这个阈值，则该节点不再生成子节点。
              <br />● 若模型在样本量多，特征也多的情况下，可适当增大该值。
            </template>
            <el-icon style="margin-left: 10px;">
              <QuestionFilled />
            </el-icon>
          </el-tooltip>
        </div>
      </div>
    </el-scrollbar>
    <template #footer>
      <span class="dialog-footer">
        <el-button @click="addSetting" type="primary">确定</el-button>
        <el-button @click="settingDialog = false"> 取消 </el-button>
      </span>
    </template>
  </el-dialog>
</template>
 
<script setup lang='ts'>
import { ref, watch, reactive, nextTick, onMounted } from 'vue';
import { emitter } from "@/utils/mitt";
import {
  SaveBSSpneuralnetworkalgorithmResult
} from "@/api/stu/SupplyChainFinance";
import Sortable from 'sortablejs'
import XBOOST from './XBOOST.vue'
import TREESVR from './TREESVR.vue'
import KNN from './KNN.vue'
import FOREST from './FOREST.vue'
import { useRoute } from "vue-router";
import {
  AlgorithmCreate,
} from "@/api/stu/SupplyChainFinance";
import {
  Plus,
  Minus,
  QuestionFilled,
  Coin,
  HelpFilled,
  Tickets
} from "@element-plus/icons-vue";
import { ElMessage } from 'element-plus';
const props = defineProps({
  showType: {
    type: String,
    required: true
  },
  //算法类型
  data: {
    type: Object,
    required: true
  },
  //算法参数对象
  showId: {
    type: String,
    required: true
  },
  detailData: {
    type: Object,
    required: true
  },
  //算法id
});
const taskTittleRegex = /^[\u4e00-\u9fffa-zA-Z0-9]{1,30}$/
const route = useRoute()
const xList = ref([])
const xListStr = ref()
const paramsList = ref([])
const acrmId = ref() //用于保存的数据id
const params: {
  ShuffleData: boolean;
  TrainingPercentage: number;
  CrossValidation: boolean;
  modelName?: string;
} = reactive({});
//Xboost参数
const XGBoostConfig: {
  BaseLearner: String;
  NumBaseLearners: number;
  LearningRate: number;
  SampleRate: number;
  TreeFeatureSamplingRate: number;
  NodeFeatureSamplingRate: number;
  MinLeafWeight: number;
  MaxTreeDepth: number;
  L1Regularization: number;
  L2Regularization: number;
} = reactive({});

//决策树回归
const decisionTreeRegressionConfig: {
  splittingCriterion: String,
  splittingFeatureCriterion: String,
  MaxFeatureRatio: String,
  FeatureRatioValue: number,
  minInternalNodeSamples: number,
  minLeafNodeSamples: number,
  minLeafNodeWeight: number,
  maxTreeDepth: number,
  maxLeafNodeCount: number,
  impurityThreshold: number
} = reactive({});

//knn
const knnConfig: {
  searchMethod: String,
  numberLeaves: number,
  nearestNeighbors: String,
  weightingFunction: String,
  distanceAlgorithm: String,
} = reactive({});

//随机森林
const randomForestRegressionConfig: {
  splittingCriterion: String,
  numDecisionTrees: number,
  bootstrapSampling: String,
  outOfBagTesting: String,
  maxFeatureRatio: String,
  featureRatioValue: number,
  minInternalNodeSamples: number,
  minLeafNodeSamples: number,
  minLeafNodeWeight: number,
  maxTreeDepth: number,
  maxLeafNodeCount: number,
  impurityThreshold: number
} = reactive({});
//控制新建完查看报告
const showDetail = ref(false)
const confirmVisible = ref(false)
//bp和svr详情数据（列表查看以及生成报告）
const bpSvrDetailData = reactive({
  mse: 0,
  rmse: 1,
  mae: 2,
  mape: 3,
  r2: 4,
  mse_test: 5,
  rmse_test: 6,
  mae_test: 7,
  mape_test: 8,
  r2_test: 9,
  bpSvrDetailHeader: [],
  y_pred_train: [], //预测训练集数据
  y_pred_test: [],//预测测试集数据
})
const lineDetaliData = reactive({
  xListStr: [],
  dataList: [],
  r2: '',
  adjustr2: '',
  f: ''
})
const tableChange = ref(1)
const HiddenLayerNeuronsList = ref([{ layerNeuron: 100 }])
const settingDialog = ref(false)
function handleDraggle(arr) {
  paramsList.value = props.data.filter((d) => arr.includes(d.dictId) && d.dictName !== "融资金额");
  xList.value = props.data.filter((d) => !arr.includes(d.dictId) && d.dictName !== "融资金额");
}

onMounted(() => {
  if (!!props.detailData) {
    handleJumpDetail()
  } else {
    paramsList.value = props.data.filter(item => item.dictName !== '融资金额')
    nextTick(() => {
      var g1 = document.getElementById('g1');
      var ops1 = {
        animation: 200,
        draggable: ".list_item",
        sort: false,
        group: { name: "itxst", pull: true, put: true },
        //拖动结束
        onEnd: function (evt) {
          var arr = sortable1.toArray();
          handleDraggle(arr)
        },
      };
      var sortable1 = Sortable.create(g1, ops1);
      //第二组
      var g2 = document.getElementById('g2');
      var ops2 = {
        animation: 200,
        draggable: ".list-item",
        sort: false,
        group: { name: "itxst", pull: true, put: true },
        //拖动结束
      };
      var sortable2 = Sortable.create(g2, ops2);
      //第三组
    })
    //处理预设数据
    handleDateDefault()
  }
})
function handleJumpDetail() {
  showDetail.value = true
  if (props.detailData.bpSvrDetailHeader) {
    xListStr.value = props.detailData.bpSvrDetailHeader.join(',')
    nextTick(() => {
      bpSvrDetailData.bpSvrDetailHeader = props.detailData.bpSvrDetailHeader
      console.log(bpSvrDetailData.bpSvrDetailHeader);
      bpSvrDetailData.mse = props.detailData.mse
      bpSvrDetailData.rmse = props.detailData.rmse
      bpSvrDetailData.mae = props.detailData.mae
      bpSvrDetailData.mape = props.detailData.mape
      bpSvrDetailData.r2 = props.detailData.r2
      bpSvrDetailData.mse_test = props.detailData.mse_test
      bpSvrDetailData.rmse_test = props.detailData.rmse_test
      bpSvrDetailData.mae_test = props.detailData.mae_test
      bpSvrDetailData.mape_test = props.detailData.mape_test
      bpSvrDetailData.r2_test = props.detailData.r2_test
      bpSvrDetailData.y_pred_test = props.detailData.y_pred_test;
      bpSvrDetailData.y_pred_train = props.detailData.y_pred_train;
      //生成Table 
      var table = document.getElementById("myTable");
      for (var i = 0; i < bpSvrDetailData.y_pred_test.length; i++) {
        var row = table.insertRow(i + 1);
        for (var j = 0; j < bpSvrDetailData.y_pred_test[i].length; j++) {
          var cell = row.insertCell(j);
          cell.innerHTML = bpSvrDetailData.y_pred_test[i][j];
          console.log(cell)
          cell.style.border = '1px solid #bab9b9';
        }
      }
    })
  }
}
// 处理预设数据
function handleDateDefault(reset) {
  params.ShuffleData = false;
  params.TrainingPercentage = 0.5;
  params.CrossValidation = false;
  if (reset) {
    paramsList.value = props.data.filter(item => item.dictName !== '融资金额')
    xList.value = []
    ElMessage.success('重置数据成功')
    Object.keys(XGBoostConfig).forEach(key => {
      delete XGBoostConfig[key];
    });
    Object.keys(decisionTreeRegressionConfig).forEach(key => {
      delete decisionTreeRegressionConfig[key];
    });
    Object.keys(knnConfig).forEach(key => {
      delete knnConfig[key];
    });
    Object.keys(randomForestRegressionConfig).forEach(key => {
      delete randomForestRegressionConfig[key];
    });
  }
}
function deleteItem(item) {
  let removedData = {}
  for (let i = 0; i < xList.value.length; i++) {
    if (xList.value[i].dictId == item.dictId) {
      // 从 group1 中删除数据
      removedData = xList.value.splice(i, 1)[0];
      break;
    }
  }
  // 将删除的数据移动到 group2
  paramsList.value.push(removedData);
}
//隐藏层参数操作

function addSetting() {
  settingDialog.value = false
  ElMessage.success('模型参数设置已保存')
}

function isEmptyReactive(obj, length) {
  console.log(Object.keys(obj).length);

  return (Object.keys(obj).length > length || Object.keys(obj).length == length)
}
async function saveParams() {
  if (xList.value.length < 5) {
    ElMessage.warning('请至少选择5个变量')
    return
  }
  const { showId, showType } = props;
  if (showType == "XGBoost回归") {
    if (!isEmptyReactive(XGBoostConfig, 10)) {
      ElMessage.warning('请在更多设置处填写参数')
      return
    }
  }
  if (showType == "决策树回归") {
    if (!isEmptyReactive(decisionTreeRegressionConfig, 9)) {
      ElMessage.warning('请在更多设置处填写所有参数')
      return
    }
  }
  if (showType == "K近邻（KNN）回归") {
    if (!isEmptyReactive(knnConfig, 4)) {
      ElMessage.warning('请在更多设置处填写所有参数')
      return
    }
  }
  if (showType == "随机森林回归") {
    if (!isEmptyReactive(randomForestRegressionConfig, 11)) {
      ElMessage.warning('请在更多设置处填写所有参数')
      return
    }
  }
  const data = {
    modelParameterSetting: '',
    modelName: '',
    ModelType: 2,
    taskId: route.query.taskId,
    planId: route.query.planId,
    indexSelection: xList.value.map(item => item.dictValue).join(',') + ',financingAmount',
    algorithmTypeId: props.showId,
    type: showType == "XGBoost回归" ? 4 : showType == '决策树回归' ? 5 : showType == 'K近邻（KNN）回归' ? 6 : 7,
    algorithmAnalysisRequestDto: {
      isApprovedMeasurement: false,
      ModelType: 2,
      querySqlString: xList.value.map(item => item.dictValue).join(',') + ',financingAmount',
      columnName: xList.value.map(item => item.dictValue).join(';') + ';financingAmount',
      selectdy: "financingAmount",
      bpStr: "",
      svrStr: "",
      algorithmTypeEnum: showType == "XGBoost回归" ? 4 : showType == '决策树回归' ? 5 : showType == 'K近邻（KNN）回归' ? 6 : 7,
      neuralNetworkParameters: '',
      algorithmParameters: '',
      updateCreditRating: ""
    },
  };
  if (showType == "XGBoost回归") {
    data.algorithmAnalysisRequestDto.xgBoostConfig = {
      shuffleData: params.ShuffleData,
      trainingPercentage: params.TrainingPercentage,
      crossValidation: params.CrossValidation,
      baseLearner: XGBoostConfig.BaseLearner || '',
      numBaseLearners: XGBoostConfig.NumBaseLearners || 0,
      learningRate: XGBoostConfig.LearningRate || 0,
      sampleRate: XGBoostConfig.SampleRate || 0,
      treeFeatureSamplingRate: XGBoostConfig.TreeFeatureSamplingRate || 0,
      nodeFeatureSamplingRate: XGBoostConfig.NodeFeatureSamplingRate || 0,
      minLeafWeight: XGBoostConfig.MinLeafWeight || 0,
      maxTreeDepth: XGBoostConfig.MaxTreeDepth || 0,
      L1Regularization: XGBoostConfig.L1Regularization || 0,
      L2Regularization: XGBoostConfig.L2Regularization || 0,
    }
    data.modelParameterSetting = JSON.stringify(data.algorithmAnalysisRequestDto.xgBoostConfig)
  }
  if (showType == "决策树回归") {
    data.algorithmAnalysisRequestDto.decisionTreeRegressionConfig = {
      shuffleData: params.ShuffleData,
      trainingPercentage: params.TrainingPercentage,
      crossValidation: params.CrossValidation,
      splittingCriterion: decisionTreeRegressionConfig.splittingCriterion || '',
      splittingFeatureCriterion: decisionTreeRegressionConfig.splittingFeatureCriterion || '',
      maxFeatureRatio: decisionTreeRegressionConfig.MaxFeatureRatio || '',
      featureRatioValue: decisionTreeRegressionConfig.MaxFeatureRatio == 'custom' ? decisionTreeRegressionConfig.FeatureRatioValue : '0.0',
      minInternalNodeSamples: decisionTreeRegressionConfig.minInternalNodeSamples || 0,
      minLeafNodeSamples: decisionTreeRegressionConfig.minLeafNodeSamples || 0,
      minLeafNodeWeight: decisionTreeRegressionConfig.minLeafNodeWeight || 0,
      maxTreeDepth: decisionTreeRegressionConfig.maxTreeDepth || 0,
      maxLeafNodeCount: decisionTreeRegressionConfig.maxLeafNodeCount || 0,
      impurityThreshold: decisionTreeRegressionConfig.impurityThreshold || 0
    }
    data.modelParameterSetting = JSON.stringify(data.algorithmAnalysisRequestDto.decisionTreeRegressionConfig)

  }
  if (showType == "K近邻（KNN）回归") {
    data.algorithmAnalysisRequestDto.knnConfig = {
      shuffleData: params.ShuffleData,
      trainingPercentage: params.TrainingPercentage,
      crossValidation: params.CrossValidation,
      searchMethod: knnConfig.searchMethod,
      numberLeaves: knnConfig.searchMethod == 'ball_tree' || knnConfig.searchMethod == 'kd_tree' ? knnConfig.numberLeaves : 2,
      nearestNeighbors: knnConfig.nearestNeighbors,
      weightingFunction: knnConfig.weightingFunction,
      distanceAlgorithm: knnConfig.distanceAlgorithm,
    }
    data.modelParameterSetting = JSON.stringify(data.algorithmAnalysisRequestDto.knnConfig)

  }
  if (showType == "随机森林回归") {
    data.algorithmAnalysisRequestDto.randomForestRegressionConfig = {
      shuffleData: params.ShuffleData,
      trainingPercentage: 0.5,
      crossValidation: params.CrossValidation,
      splittingCriterion: randomForestRegressionConfig.splittingCriterion || '',
      numDecisionTrees: randomForestRegressionConfig.numDecisionTrees || 0,
      bootstrapSampling: 'true',
      outOfBagTesting: 'true',
      maxFeatureRatio: '无',
      featureRatioValue: randomForestRegressionConfig.maxFeatureRatio == 'custom' ? randomForestRegressionConfig.featureRatioValue : '0.0',
      minInternalNodeSamples: randomForestRegressionConfig.minInternalNodeSamples || 0,
      minLeafNodeSamples: randomForestRegressionConfig.minLeafNodeSamples || 0,
      minLeafNodeWeight: randomForestRegressionConfig.minLeafNodeWeight || 0,
      maxTreeDepth: randomForestRegressionConfig.maxTreeDepth || 0,
      maxLeafNodeCount: randomForestRegressionConfig.maxLeafNodeCount || 0,
      impurityThreshold: randomForestRegressionConfig.impurityThreshold || 0
    }
    data.modelParameterSetting = JSON.stringify(data.algorithmAnalysisRequestDto.randomForestRegressionConfig)
  }
  //根据类型传递对应的参数
  let res = await AlgorithmCreate(data)
  if (res.success) {
    handleNewReport(res.data)
  } else {
    ElMessage.error(res.msg)
  }
}


function handleNewReport(data) {
  showDetail.value = true
  acrmId.value = data.acrmId
  xListStr.value = xList.value.map(item => item.dictName).join(',')
  nextTick(() => {
    bpSvrDetailData.bpSvrDetailHeader = xList.value.map(item => item.dictName)
    const head = xList.value.map(item => item.dictValue)
    const result = []; //测试集
    const result1 = [];//训练集
    acrmId.value = data.acrmId
    bpSvrDetailData.mse = data.mse
    bpSvrDetailData.rmse = data.rmse
    bpSvrDetailData.mae = data.mae
    bpSvrDetailData.mape = data.mape
    bpSvrDetailData.r2 = data.r2
    bpSvrDetailData.mse_test = data.mse_test
    bpSvrDetailData.rmse_test = data.rmse_test
    bpSvrDetailData.mae_test = data.mae_test
    bpSvrDetailData.mape_test = data.mape_test
    bpSvrDetailData.r2_test = data.r2_test
    //处理测试集数据
    for (const obj of data.test_quotaAssessment_data) {
      const item = [];
      for (const property of head) {
        item.push(obj[property]);
      }
      result.push(item);
    }
    for (let i = 0; i < result.length; i++) {
      result[i].unshift(data.y_pred_test[i]);
    }
    //处理训练集数据
    for (const obj of data.quotaAssessment_data) {
      const item = [];
      for (const property of head) {
        item.push(obj[property]);
      }
      result1.push(item);
    }
    for (let i = 0; i < result1.length; i++) {
      result1[i].unshift(data.y_pred_train[i]);
    }
    bpSvrDetailData.y_pred_test = result;
    bpSvrDetailData.y_pred_train = result1;
    //生成Table 
    var table = document.getElementById("myTable");
    console.log(result.length)
    for (var i = 0; i < result.length; i++) {
      var row = table.insertRow(i + 1);
      for (var j = 0; j < result[i].length; j++) {
        var cell = row.insertCell(j);
        cell.innerHTML = result[i][j];
        console.log(cell)
        cell.style.border = '1px solid #bab9b9';
      }
    }
  })
}



function hanldeChangeTable() {
  if (tableChange.value == 1) {
    return
  } else {
    nextTick(() => {
      var table = document.getElementById("myTable1");
      for (var i = 0; i < bpSvrDetailData.y_pred_train.length; i++) {
        var row = table.insertRow(i + 1);
        for (var j = 0; j < bpSvrDetailData.y_pred_train[i].length; j++) {
          var cell = row.insertCell(j);
          cell.innerHTML = bpSvrDetailData.y_pred_train[i][j];
          cell.style.border = '1px solid #bab9b9';
        }
      }
    })
  }
}

async function saveSSS() {
  if (params.modelName == '') {
    ElMessage.warning('请输入模型名称')
    return
  }
  if (taskTittleRegex.test(params.modelName) == false) {
    ElMessage.warning('模型名称不得输入特殊字符,不得重复，且长度为1-30个字符')
    return
  }
  const { showId, showType } = props;
  const data = {
    AlgorithmModelName: params.modelName,
    taskId: route.query.taskId,
    planId: route.query.planId,
    type: showType == "XGBoost回归" ? 4 : showType == '决策树回归' ? 5 : showType == 'K近邻（KNN）回归' ? 6 : 7,
    acrmId: acrmId.value,
    algorithmCalculateResult: JSON.stringify(bpSvrDetailData),
    modelType: 2,
    BpSvrDetailHeader: '融资金额,' + xList.value.map(item => item.dictName).join(',')
  }
  let res = await SaveBSSpneuralnetworkalgorithmResult(data)
  if (res.success) {
    confirmVisible.value = false
    showDetail.value = false
    emitter.emit('closeNewApprove')
    emitter.emit('refreshTableApprove')
    ElMessage.success('新增额度核定模型成功！')
  } else {
    ElMessage.error(res.msg)
  }
}


function backToNew() {
  showDetail.value = false
  tableChange.value = 1
}
</script>
<style>
.box-item-draggle {
  max-width: 50%;
}
</style>
<style scoped lang="scss" >
.container {
  height: 100%;
  display: flex;
}

.left-panel {
  width: 200px;
  border-right: 1px solid #eef1f5;
  user-select: none;
}

.flexible-panel {
  flex-grow: 1;
  overflow-y: auto;
  overflow-x: hidden;
  flex: 1;
}

.list_item {
  padding: 0 12px 0 20px;
  font-size: 12px;
  cursor: move;
  color: #6a6f77;
  align-items: center;
  margin-bottom: 12px;
}

.top-title {
  padding: 10px 12px 10px 20px;
  margin-bottom: 15px;
  border-bottom: 1px solid #eef1f5;
  display: flex;
  justify-content: space-between
}

.var-des {
  padding: 18px 20px;
  font-size: 12px;
}

.drag-area {
  margin-left: 20px;
  border: 1px dashed #d8d8d8;
  overflow-y: auto;
  min-height: 40px;
  flex-basis: 40px;
  height: 40px;
  flex-grow: 0;
}

.drag-areax {
  margin-left: 20px;
  border: 1px dashed #d8d8d8;
  overflow-y: auto;
  min-height: 240px;
  flex-basis: 40px;
  height: 40px;
  flex-grow: 0;
}

.drag-box {
  width: 100%;
  height: 100%;
  position: relative;
}

.yStyle {
  height: 100%;
  width: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  color: #aaadb1;
  font-size: 14px;
  position: absolute;
  left: 0;
  top: 0;
}

.list-item {
  height: 30px;
  font-size: 12px;
  padding: 0 20px;
  align-items: center;
  cursor: move;
  justify-content: space-between;
  display: flex;
  user-select: none;
}

.close-icon {
  position: relative;
  display: inline-block;
  width: 20px;
  height: 20px;
  cursor: pointer;
}

.close-icon::before,
.close-icon::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: 2px;
  height: 10px;
  background-color: red;
  transform: translate(-50%, -50%) rotate(45deg);
}

.close-icon::before {
  transform: translate(-50%, -50%) rotate(-45deg);
}

.condition {
  margin-top: 15px;
  margin-left: 20px;
  display: flex;
}

.paramsBottom {
  display: flex;
  align-items: center;
  font-size: 12px;
}

.detail {
  color: #1a78ff;
  cursor: pointer;
  font-size: 12px;
  display: inline-flex;
  flex-wrap: nowrap;
}

.setting-item {
  display: flex;
  align-items: center;
  margin-top: 10px;
}

.foot-buttom {
  display: flex;
  text-align: right;
  justify-content: center;
  margin-top: 50px;
}

.result-header {
  padding: 0px 30px px;
  height: 40px;
  width: 100%;
  line-height: 40px;
  font-family: PingFangSC, PingFangSC-Medium;
  text-align: left;
  color: #2b323d;
  border-bottom: 1px solid #eef1f5;
}

.analy-result-process-wrap {
  margin-top: 16px;
  margin-bottom: 20px;
  font-family: PingFangSC, PingFangSC-Medium;
}

.analy-result-process-header {
  color: rgb(43, 50, 61);
  height: 22px;
  margin-bottom: 16px;
  font-weight: 700;
  display: flex;
  font-size: 14px;
  align-items: center;
}

.analy-result-process-header::before {
  content: "";
  width: 4px;
  height: 16px;
  margin-right: 10px;
  background-color: rgb(26, 120, 255);
}

.analy-result-process-content {
  margin-left: 14px;
}

.process-header {
  display: flex;
  font-size: 14px;
  align-items: center;
  color: rgb(43, 50, 61);
  margin: 10px 0px 8px;
}

.database {
  color: rgb(26, 120, 255);
  margin-right: 8px
}

.process-body {
  margin-left: 14px;
  padding-left: 22px;
  border-left: 1px solid rgba(26, 120, 255, 0.3);
  min-height: 28px;
  line-height: 12px;
  position: relative;
  font-weight: 400;
  font-size: 12px;
}

.process-body::before {
  content: "";
  width: 0px;
  height: 0px;
  border-width: 4px;
  border-style: solid;
  border-image: initial;
  border-color: rgba(26, 120, 255, 0.5) transparent transparent;
  position: absolute;
  left: -4px;
  bottom: -8px;
  translate: -0.5px;
}

.body-1 {
  text-decoration: underline;
  color: rgb(26, 120, 255);
  line-height: 18px;
  cursor: pointer;
}

.body-p {
  color: rgb(106, 111, 119);
  line-height: 18px;
  margin-bottom: 4px;
  width: 100%;
}


table,
th,
td {
  border: 1px solid #bab9b9;
  border-collapse: collapse;
}

.analy-step {
  margin-bottom: 40px;
  margin-top: 16px;
  font-size: 14px;
}

.step-text {
  margin-left: 14px;
  font-family: PingFangSC, PingFangSC-Regular;
  font-weight: 400;
  color: #6a6f77;
  white-space: pre-wrap;
}

.result-table {
  margin-bottom: 20px;
  margin-left: 20px
}

.sub-title-text {
  font-family: PingFangSC, PingFangSC-Medium;
  font-weight: 700;
  color: #2b323d;
  height: 26px;
  display: flex;
  align-items: center;
  margin-bottom: 20px;
}
</style>
